home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / endo / keyboard.c < prev    next >
C/C++ Source or Header  |  1995-05-12  |  29KB  |  1,037 lines

  1. /*************************************************************************
  2.  *                                                                       *
  3.  *  Copyright (c) 1992, 1993 Ronald Joe Record                           *
  4.  *                                                                       *
  5.  *  All rights reserved. No part of this program or publication may be   *
  6.  *  reproduced, transmitted, transcribed, stored in a retrieval system,  *
  7.  *  or translated into any language or computer language, in any form or *
  8.  *  by any means, electronic, mechanical, magnetic, optical, chemical,   *
  9.  *  biological, or otherwise, without the prior written permission of:   *
  10.  *                                                                       *
  11.  *      Ronald Joe Record (408) 458-3718                                 *
  12.  *      212 Owen St., Santa Cruz, California 95062 USA                   *
  13.  *                                                                       *
  14.  *************************************************************************/
  15.  
  16. #include <stdio.h>
  17. #include <values.h>
  18. #include "x.h"
  19. #ifdef USE_3D
  20. #include "globals.h"
  21. #endif
  22.  
  23. #define MAX_HISTEX 4
  24. #define MIN_HISTEX -4
  25. #define ADELTA 0.05
  26. #define BDELTA 0.1
  27.  
  28. int cornerbar = 1;
  29. static int ishow=1;
  30.  
  31. extern void init_color(), recalc(), print_help(), Save_Parms();
  32. extern void HistoMem(), FreeHist(), CritiMem(), FreeCrit(), rehist();
  33. extern void go_init(), go_back(), go_down(), Clear(), Draw_Axes();
  34. extern void save_to_file(), Redraw(), redraw(), Show_Maps(); 
  35. extern void Redraw_Hist(), Draw_Diagonal(), flood(), rebasin(), fillbar();
  36. #ifdef USE_3D
  37. extern void SetWindow(), TranslateWindow(), ScaleWindow(); 
  38. extern void TranslateView();
  39. #endif
  40.  
  41. void
  42. dump_colmap() {
  43.     FILE *map;
  44.     int a, b, c, i;
  45.     char buf[255];
  46.  
  47.     sprintf(buf,"colormap%d.map",numwheels);
  48.     if ((map = fopen(buf, "w")) == NULL)
  49.         perror(buf);
  50.     else {
  51.         for (i=0; i<numcolors; i++) {
  52.             a = Colors[i].red / 256;
  53.             b = Colors[i].green / 256;
  54.             c = Colors[i].blue / 256;
  55.             sprintf(buf,"%d %d %d\n",a,b,c);
  56.             fputs(buf, map);
  57.         }
  58.     }
  59. }
  60.  
  61. void
  62. GetSpecial(event, c)
  63. XKeyEvent *event;
  64. unsigned char c;
  65. {
  66.     static int set_sea=1;
  67.     static int i;
  68.     static double tx;
  69.     extern int numeric, axes, see_domain, model_1d, orbits_1d, updt, adown;
  70.     extern int orbit_in_basin, pdown, orbit_in_precrit, numattrs, _numdivs;
  71.     extern int maxcrit, histex, maxhist, minhist, start, nonleg, cdown;
  72.     extern int orbit_in_crit, tdown;
  73.     extern short delay;
  74.     extern double A, B, C, D, sky_level, sea_level;
  75.     extern void Draw_Therm(), Erase_Therm();
  76.  
  77.     switch (c) {
  78.     case '0': if (event->window == trajec) { /* Zoom out, doubling edges */
  79.             t_min_x -= t_x_range/2;
  80.             t_min_y -= t_y_range/2;
  81.             t_x_range += t_x_range;
  82.             t_y_range += t_y_range;
  83.           }
  84.           else if (event->window == crijec) {
  85.             c_min_x -= c_x_range/2;
  86.             c_min_y -= c_y_range/2;
  87.             c_x_range += c_x_range;
  88.             c_y_range += c_y_range;
  89.           }
  90.           else {
  91.             min_x -= x_range/2;
  92.             min_y -= y_range/2;
  93.             x_range += x_range;
  94.             y_range += y_range;
  95.             newframe();
  96.           }
  97.           SetFocus(event->window);
  98.           break;
  99.     case '1': model_1d = (!model_1d);
  100.           break;
  101.     case '2': orbits_1d++;
  102.           if (orbits_1d >= 4)
  103.             orbits_1d = 0;
  104.           init_color(dpy, trajec, cmap, Colors, STARTCOLOR, MINCOLINDEX,
  105.                     numcolors, numwheels, "endo", "Endo", numattrs);
  106.           Clear(trajec);
  107.           break;
  108. #ifdef USE_3D
  109.     case '3': orbits_3d=(!orbits_3d);
  110.           Clear(trajec);
  111.           break;
  112. #endif
  113.     case '4': see_domain = (!see_domain);
  114.           break;
  115.     case '5': if (event->window == trajec) /* Pan Left by half the width */
  116.             t_min_x -= t_x_range/2.0;
  117.           else if (event->window == crijec)
  118.             c_min_x -= c_x_range/2.0;
  119.           else {
  120.             min_x -= x_range/2.0;
  121.             newframe();
  122.           }
  123.           SetFocus(event->window);
  124.           break;
  125.     case '6': if (event->window == trajec) /* Pan Right by half the width */
  126.             t_min_x += t_x_range/2.0;
  127.           else if (event->window == crijec)
  128.             c_min_x += c_x_range/2.0;
  129.           else {
  130.             min_x += x_range/2.0;
  131.             newframe();
  132.           }
  133.           SetFocus(event->window);
  134.           break;
  135.     case '7': if (event->window == trajec) /* Pan down by half the height */
  136.             t_min_y -= t_y_range/2.0;
  137.           else if (event->window == crijec)
  138.             c_min_y -= c_y_range/2.0;
  139.           else {
  140.             min_y -= y_range/2.0;
  141.             newframe();
  142.           }
  143.           SetFocus(event->window);
  144.           break;
  145.     case '8': if (event->window == trajec) /* Pan up by half the height */
  146.             t_min_y += t_y_range/2.0;
  147.           else if (event->window == crijec)
  148.             c_min_y += c_y_range/2.0;
  149.           else {
  150.             min_y += y_range/2.0;
  151.             newframe();
  152.           }
  153.           SetFocus(event->window);
  154.           break;
  155.     case '9': if (event->window == trajec) { /* Zoom in to center quarter */
  156.             t_min_x += t_x_range/4;
  157.             t_min_y += t_y_range/4;
  158.             t_x_range -= t_x_range/2;
  159.             t_y_range -= t_y_range/2;
  160.           }
  161.           else if (event->window == crijec) {
  162.             c_min_x += c_x_range/4;
  163.             c_min_y += c_y_range/4;
  164.             c_x_range -= c_x_range/2;
  165.             c_y_range -= c_y_range/2;
  166.           }
  167.           else {
  168.             min_x += x_range/4;
  169.             min_y += y_range/4;
  170.             x_range -= x_range/2;
  171.             y_range -= y_range/2;
  172.             newframe();
  173.           }
  174.           SetFocus(event->window);
  175.           break;
  176.     case '<': dwell /= 2; if (dwell < 1) dwell = 1; break;
  177.     case '>': dwell *= 2;
  178.           freecoords();
  179.           setupcoords();
  180.           break;
  181.     case '(': delay -= 25; if (delay < 0) delay=0; break;
  182.     case ')': delay += 25; break;
  183.     case '[': settle /= 2; if (settle < 1) settle = 0; break;
  184.     case ']': settle *= 2; if (settle < 1) settle = 1; break;
  185.     case '{': delta /= 2.0; break;
  186.     case '}': delta *= 2.0; break;
  187.     case '-': cdelt /= 2.0; break;
  188.     case '+': cdelt *= 2.0; break;
  189.     case '^': 
  190.     case '%':
  191.             if (portrait && histogram)
  192.                   Redraw_Hist(); break;
  193. #ifdef USE_3D
  194.     case '.': SetWindow(3);
  195.           Clear(trajec);
  196.           break;
  197.     case ',': SetWindow(2);
  198.           Clear(trajec);
  199.           break;
  200. #endif
  201.     case '/': Draw_Diagonal(event->window);
  202.           break;
  203.     case '|': axes = (!axes);
  204.           Draw_Axes(event->window, axes);
  205.           break;
  206.     case '#': numeric = (!numeric);
  207.           if (numeric)
  208.             deriv = dnumeric;
  209.           else
  210.               deriv = Derivs[mapindex];
  211.           break;
  212.     case '\001': /* ctrl-A toggles setting sea_level and sky_level */
  213.             set_sea = (!set_sea);
  214.             break;
  215.     case '\002': /* ctrl-B  toggles color bar display */
  216.             showbar++;
  217.             if (showbar > 2)
  218.                 showbar = 0;
  219.             if (showbar == 1) {
  220.                 XMapRaised(dpy, hisbar);
  221.                   init_color(dpy, hisbar, cmap, Colors, STARTCOLOR, MINCOLINDEX,
  222.                     numcolors, numwheels, "endo", "Endo", numattrs);
  223.                 fillbar(hisbar, HISBARHGT, HISBARHGT, cornerbar);
  224.             }
  225.             else if (showbar == 2) {
  226.                 fillbar(trajec, traheight/2, traheight, cornerbar);
  227.                 XUnmapWindow(dpy, hisbar);
  228.             }
  229.             else {
  230.                 if (cornerbar)
  231.                     XFillRectangle(dpy, pixtra, Data_GC[0], 
  232.                         0, traheight/2, HISBARWID, traheight/2);
  233.                 else
  234.                     XFillRectangle(dpy, pixtra, Data_GC[0], 
  235.                         0, 0, HISBARWID, traheight/2);
  236.                 XCopyArea(dpy, pixtra, trajec, Data_GC[0],
  237.                     0, 0, trawidth, traheight, 0, 0);
  238.             }
  239.             break;
  240.     case '\003': /* (ctrl-C) toggle drawing trajectory in critical window */
  241.           orbit_in_crit = (!orbit_in_crit);
  242.           if (orbit_in_crit) {
  243.             if (cdown) {
  244.                 XMapRaised(dpy, crijec);
  245.                 stacktop = crijec;
  246.                   init_color(dpy,crijec,cmap,Colors,STARTCOLOR,MINCOLINDEX,
  247.                             numcolors,numwheels,"endo","Endo", numattrs);
  248.                 cdown=0;
  249.                 if (thermometer)
  250.                     Draw_Therm(crijec, pixcri, criwidth, criheight);
  251.             }
  252.           }
  253.           break;
  254.     case '\005':  /* (ctrl-E) recalculate colors for basins */
  255.           rebasin();
  256.           redraw(indices[frame], perind[frame], 1);
  257.           ishow=0; break;
  258.     case '\006':  /* (ctrl-F) set sea or sky level to 1.0 */
  259.         if (set_sea) {
  260.           if (sea_level != 1.0) {
  261.               tx = sea_level;
  262.               sea_level = 1.0;
  263.               i = maxhist - minhist;
  264.               flood(1, 1, (int)(tx*(double)i)+minhist, maxhist);
  265.           }
  266.         }
  267.         else {
  268.           if (sky_level != 1.0) {
  269.               tx = sky_level;
  270.               sky_level = 1.0;
  271.               i = maxhist - minhist;
  272.               flood(0, 1, (int)(tx*(double)i)+minhist, MAXINT);
  273.           }
  274.         }
  275.           break;
  276.     case '\007':  /* (ctrl-G) set sea level back to 0.0 */
  277.         if (set_sea)
  278.           if (sea_level) {
  279.               tx = sea_level;
  280.               sea_level = 0.0;
  281.               i = maxhist - minhist;
  282.               flood(1, 0, (int)(tx*(double)i)+minhist, 1);
  283.           }
  284.         else
  285.           if (sky_level) {
  286.               tx = sky_level;
  287.               sky_level = 0.0;
  288.               i = maxhist - minhist;
  289.               flood(0, 0, (int)(tx*(double)i)+minhist, 1);
  290.           }
  291.           break;
  292.     case '\010':  /* (ctrl-H) decrement sea level by lesser of color, hit */
  293.           tx = Min((1.0 / (double)(numcolors - start - 1)),
  294.                    (1.0 / (double)(maxhist - minhist)));
  295.         if (set_sea) {
  296.           sea_level -= tx;
  297.           if (sea_level < 0.0)
  298.               sea_level = 0.0;
  299.           i = (int)(sea_level * (double)(maxhist - minhist)) + minhist;
  300.           flood(1, 0, i + (int)(tx*(double)(maxhist - minhist)), 
  301.                 Max(1,i - (int)(tx*(double)(maxhist - minhist))));
  302.         }
  303.         else {
  304.           sky_level -= tx;
  305.           if (sky_level < 0.0)
  306.               sky_level = 0.0;
  307.           i = (int)(sky_level * (double)(maxhist - minhist)) + minhist;
  308.           flood(0, 0, i + (int)(tx*(double)(maxhist - minhist)), 
  309.                 Max(1,i - (int)(tx*(double)(maxhist - minhist))));
  310.         }
  311.           break;
  312.     case '\011':  /* (ctrl-I) toggles color bar display algorithm */
  313.             nonleg = (!nonleg);
  314.             if (showbar == 1)
  315.                 fillbar(hisbar, HISBARHGT, HISBARHGT, cornerbar);
  316.             else if (showbar == 2)
  317.                 fillbar(trajec, traheight/2, traheight, cornerbar);
  318.             break;
  319.     case '\012':  /* (ctrl-J) increment sea level by lesser of color, hit */
  320.           tx = Min((1.0 / (double)(numcolors - start - 1)),
  321.                    (1.0 / (double)(maxhist - minhist)));
  322.         if (set_sea) {
  323.           sea_level += tx;
  324.           if (sea_level > 1.0)
  325.               sea_level = 1.0;
  326.           i = (int)(sea_level * (double)(maxhist - minhist)) + minhist;
  327.           flood(1, 1, i - (int)(tx*(double)(maxhist - minhist)), i);
  328.         }
  329.         else {
  330.           sky_level += tx;
  331.           if (sky_level > 1.0)
  332.               sky_level = 1.0;
  333.           i = (int)(sky_level * (double)(maxhist - minhist)) + minhist;
  334.           flood(0, 1, i - (int)(tx*(double)(maxhist - minhist)), i);
  335.         }
  336.           break;
  337.     case '\013':  /* (ctrl-K) decrement histogram algorithm index */
  338.           if (adjcol)
  339.             drawmap(A, B, C, D);
  340.           histex--;
  341.           if (histex < MIN_HISTEX)
  342.               histex = MAX_HISTEX;
  343.           if (adjcol)
  344.             drawmap(A, B, C, D);
  345.           rehist();
  346.           if (showbar == 1)
  347.             fillbar(hisbar, HISBARHGT, HISBARHGT, cornerbar);
  348.           else if (showbar == 2)
  349.             fillbar(trajec, traheight/2, traheight, cornerbar);
  350.           break;
  351.     case '\014':  /* (ctrl-L) increment histogram algorithm index */
  352.           if (adjcol)
  353.             drawmap(A, B, C, D);
  354.           histex++;
  355.           if (histex > MAX_HISTEX)
  356.               histex = MIN_HISTEX;
  357.           if (adjcol)
  358.             drawmap(A, B, C, D);
  359.           rehist();
  360.           if (showbar == 1)
  361.             fillbar(hisbar, HISBARHGT, HISBARHGT, cornerbar);
  362.           else if (showbar == 2)
  363.             fillbar(trajec, traheight/2, traheight, cornerbar);
  364.           break;
  365.     case '\015': /* ctrl-M */ 
  366.           maxcrit /= 2; break;
  367.     case '\016': /* ctrl-N */ 
  368.           maxcrit *= 2; if (maxcrit < 1) maxcrit = 1; break;
  369.     case '\017': /* ctrl-O toggles corner in which color bar is drawn */ 
  370.           cornerbar = (!cornerbar); break;
  371.     case '\020':     /* (ctrl-P) toggle drawing trajectory in basin */
  372.           orbit_in_basin = (!orbit_in_basin);
  373.           if (orbit_in_basin) {
  374.             if (adown) {
  375.                 XMapRaised(dpy, canvas);
  376.                 stacktop = canvas;
  377.                 which = canvas;
  378.                 init_color(dpy,canvas,cmap,Colors,STARTCOLOR,MINCOLINDEX,
  379.                             numcolors,numwheels,"endo","Endo", numattrs);
  380.                 adown=0;
  381.                 if (thermometer)
  382.                     Draw_Therm(canvas, pixmap, width, height);
  383.             }
  384.           }
  385.           break;
  386.     case '\021': run = 1;        /* ctrl-Q resumes computation */
  387.           break;
  388.     case '\022': dump_colmap();        /* ctrl-R dumps the color map to a file */
  389.           break;
  390.     case '\023': run = 0;        /* ctrl-S pauses computation */
  391.           break;
  392.     case '\024':  /* (ctrl-T) toggle drawing trajectory in precrit window */
  393.           orbit_in_precrit = (!orbit_in_precrit);
  394.           if (orbit_in_precrit) {
  395.             if (pdown) {
  396.                 XMapRaised(dpy, prejec);
  397.                 stacktop = prejec;
  398.                 init_color(dpy,prejec,cmap,Colors,STARTCOLOR,MINCOLINDEX,
  399.                             numcolors,numwheels,"endo","Endo", numattrs);
  400.                 pdown=0;
  401.             }
  402.           }
  403.           break;
  404.     case '\025': /* ctrl-U toggles scale display in color window */
  405.             updt = (!updt); break;
  406.     case '\026': adjcol = (!adjcol);    /* ctrl-V toggles color adjust window */
  407.             if (adjcol) {
  408.                 XMapRaised(dpy, colwin);
  409.                 init_color(dpy,colwin,cmap,Colors,STARTCOLOR,MINCOLINDEX,
  410.                             numcolors,numwheels,"endo","Endo", numattrs);
  411.                 drawmap(A, B, C, D);
  412.             }
  413.             else
  414.                 XUnmapWindow(dpy, colwin);
  415.           break;
  416.     case '\027':  /* (ctrl-W) set color palette to black & white */
  417.             if (numwheels == -2)
  418.                 numwheels = -1; /* all white (for debug purposes) */
  419.             else
  420.                 numwheels = -2;
  421.                init_color(dpy,stacktop,cmap,Colors,STARTCOLOR,MINCOLINDEX,
  422.                         numcolors,numwheels,"endo","Endo", numattrs);
  423.            ishow=0; break;
  424.     case '\030':  /* (ctrl-X) decrease divisions in rainbow palette */
  425.            if (_numdivs > 1)
  426.             _numdivs--;
  427.            else
  428.             _numdivs = MAXDIVS;
  429.                init_color(dpy,stacktop,cmap,Colors,STARTCOLOR,MINCOLINDEX,
  430.                         numcolors,numwheels,"endo","Endo", numattrs);
  431.             ishow=0; break;
  432.     case '\031':  /* (ctrl-Y) increase divisions in rainbow palette */
  433.            if (_numdivs < MAXDIVS)
  434.             _numdivs++;
  435.            else
  436.             _numdivs = 1;
  437.                init_color(dpy,stacktop,cmap,Colors,STARTCOLOR,MINCOLINDEX,
  438.                         numcolors,numwheels,"endo","Endo", numattrs);
  439.            ishow=0; break;
  440.     case '\033': /* ctrl-[ */
  441.             if (adjcol)
  442.                 drawmap(A, B, C, D);
  443.             A -= ADELTA*A;    /* ctrl-[ moves (A,m*B) in */
  444.             if (A < 0.0) A=0.0; /* get_hist_index() to left */
  445.             if (adjcol)
  446.                 drawmap(A, B, C, D);
  447.             Redraw_Hist();
  448.             break;
  449.     case '\035': /* ctrl-] */
  450.             if (adjcol)
  451.                 drawmap(A, B, C, D);
  452.             A += ADELTA*(1.0-A);    /* ctrl-] moves (A,m*B) in */
  453.             if (A > 1.0) A=1.0;         /* get_hist_index() to right */
  454.             if (adjcol)
  455.                 drawmap(A, B, C, D);
  456.             Redraw_Hist();
  457.             break;
  458.     case '\036': /* ctrl-^ */
  459.             if (adjcol)
  460.                 drawmap(A, B, C, D);
  461.             B += BDELTA*(1.0-B);    /* ctrl-^ moves (A,m*B) in */
  462.             if (B > 1.0) B=1.0;         /* get_hist_index() upward */
  463.             if (adjcol)
  464.                 drawmap(A, B, C, D);
  465.             Redraw_Hist();
  466.             break;
  467.     case '\037': /* ctrl-_ */
  468.             if (adjcol)
  469.                 drawmap(A, B, C, D);
  470.             B -= BDELTA*B;    /* ctrl-_ moves (A,m*B) in */
  471.             if (B < 0.0) B=0.0; /* get_hist_index() downward */
  472.             if (adjcol)
  473.                 drawmap(A, B, C, D);
  474.             Redraw_Hist();
  475.             break;
  476.     case '\041': /* (!) toggle drawing thermometer */
  477.           freemem();
  478.           if (histogram)
  479.             FreeHist();
  480.           if (critical)
  481.             FreeCrit();
  482.           Clear(trajec);
  483.           Clear(canvas);
  484.           Clear(crijec);
  485.           thermometer = (!thermometer);
  486.           Clear(trajec);
  487.           Clear(canvas);
  488.           Clear(crijec);
  489.           setupmem();
  490.           if (histogram)
  491.             HistoMem();
  492.           if (critical)
  493.             CritiMem();
  494.           if (thermometer) {
  495.             if (!tdown)
  496.                 Draw_Therm(trajec, pixtra, trawidth, traheight);
  497.             if (!adown)
  498.                 Draw_Therm(canvas, pixmap, width, height);
  499.             if (!cdown)
  500.                 Draw_Therm(crijec, pixcri, criwidth, criheight);
  501.           }
  502.           else {
  503.             if (!tdown)
  504.                 Erase_Therm(trajec, pixtra, trawidth, traheight);
  505.             if (!adown)
  506.                 Erase_Therm(canvas, pixmap, width, height);
  507.             if (!cdown)
  508.                 Erase_Therm(crijec, pixcri, criwidth, criheight);
  509.           }
  510.           Redraw();
  511.           break;
  512.     }
  513. }
  514.  
  515. void
  516. Getkey(event)
  517. XKeyEvent *event;
  518. {
  519.     unsigned char key;
  520.     XKeyEvent *keyevent = (XKeyEvent *)event;
  521.     static int i, dorecalc=0, olyap=-1; 
  522.     static int spinning=0, spindir=0;
  523.     static pair t0;
  524.     static double tx, ty;
  525.     static triple tvector;
  526.     static XWindowChanges values;
  527.     static XWindowAttributes attr;
  528.     extern short delay;
  529.     extern int found_arc, negative, lowrange, axes, orbits_1d;
  530.     extern int pdown, cdown, adown, tdown, ldown, idown;
  531.     extern int model_1d, animate, mandel, numeric, numattrs;
  532.     extern int first, second, begin, middle, see_domain, use_avg_lyap;
  533.     extern triple window_center; 
  534.     extern double window_distance, avg();
  535.     extern void Draw_Therm();
  536.  
  537.     ishow = 1;
  538.     if (XLookupString(keyevent, (char *)&key, sizeof(key), (KeySym *)0,
  539.         (XComposeStatus *)0) > 0)
  540.     switch (key) {
  541.     case 'a': use_avg_lyap = (!use_avg_lyap); break;
  542.     case 'A': if (critical) remap_arcs(); ishow=0; break;
  543.     case 'b': if (which == canvas) {
  544.                 ldown = (!ldown);
  545.                 if (ldown)
  546.                     XUnmapWindow(dpy,lyajec);
  547.                 else {
  548.                     XMapRaised(dpy, lyajec);
  549.                     stacktop = lyajec;
  550.                     which = lyajec;
  551.                       init_color(dpy,lyajec,cmap,Colors,STARTCOLOR,MINCOLINDEX,
  552.                                 numcolors,numwheels,"endo","Endo", numattrs);
  553.                 }
  554.               }
  555.               else {
  556.                 adown = (!adown);
  557.                 if (adown)
  558.                     XUnmapWindow(dpy,canvas);
  559.                 else {
  560.                     XMapRaised(dpy, canvas);
  561.                     stacktop = canvas;
  562.                     which = canvas;
  563.                       init_color(dpy,canvas,cmap,Colors,STARTCOLOR,MINCOLINDEX,
  564.                                 numcolors,numwheels,"endo","Endo", numattrs);
  565.                     if (thermometer)
  566.                         Draw_Therm(canvas, pixmap, width, height);
  567.                 }
  568.               }
  569.               ishow=0; break;
  570.     case 'B': adown = (!adown);
  571.           ldown = (!ldown);
  572.           if (ldown) {
  573.             XUnmapWindow(dpy,lyajec);
  574.           }
  575.           else {
  576.             XMapRaised(dpy, lyajec);
  577.             stacktop = lyajec;
  578.             which = lyajec;
  579.               init_color(dpy,lyajec,cmap,Colors,STARTCOLOR,MINCOLINDEX,
  580.                             numcolors,numwheels,"endo","Endo", numattrs);
  581.           }
  582.           if (adown) {
  583.             XUnmapWindow(dpy,canvas);
  584.           }
  585.           else {
  586.             XMapRaised(dpy, canvas);
  587.             stacktop = canvas;
  588.             which = canvas;
  589.               init_color(dpy,canvas,cmap,Colors,STARTCOLOR,MINCOLINDEX,
  590.                             numcolors,numwheels,"endo","Endo", numattrs);
  591.             if (thermometer)
  592.                 Draw_Therm(canvas, pixmap, width, height);
  593.           }
  594.           ishow=0; break;
  595.     case 'c': Clear(trajec); ishow=0; break;
  596.     case 'C': cdown = (!cdown);
  597.           if (cdown) {
  598.             XUnmapWindow(dpy,crijec);
  599.             critical = 0;
  600.           }
  601.           else {
  602.             XMapRaised(dpy, crijec);
  603.             stacktop = crijec;
  604.               init_color(dpy,crijec,cmap,Colors,STARTCOLOR,MINCOLINDEX,
  605.                             numcolors,numwheels,"endo","Endo", numattrs);
  606.             critical = 1;
  607.             if (thermometer)
  608.                 Draw_Therm(crijec, pixcri, criwidth, criheight);
  609.           }
  610.           if (critical)
  611.             CritiMem();
  612.           else
  613.             FreeCrit();
  614.           ishow=0; break;
  615.     case 'd': go_down(); break;
  616.     case 'D': AllFlushBuffer(); ishow=0; break;
  617.     case 'e': animate = (!animate); break;
  618.     case 'E': AllFlushBuffer();
  619.           dorecalc = (!dorecalc);
  620.           rehist();
  621.           if (dorecalc)
  622.             recalc(); 
  623.           else {
  624.             if (lyap) {
  625.                 for (i=0;i<perind[frame];i++) {
  626.                     if (indices[frame][i] < MINCOLINDEX) {
  627.                         indices[frame][i] = (periods[frame][i] 
  628.                                             % lowrange) + STARTCOLOR;
  629.                     }
  630.                     else {
  631.                         indices[frame][i] = (periods[frame][i] 
  632.                                             % (numfreecols-1)) + MINCOLINDEX;
  633.                     }
  634.                 }
  635.             }
  636.             else {
  637.                 for (i=0;i<perind[frame];i++) {
  638.                   if ((!find) || (basins[frame][i])) {
  639.                     if (periods[frame][i] < 0) {
  640.                            indices[frame][i] = (ABS(periods[frame][i])
  641.                                             % first) + begin;
  642.                     }
  643.                     else {
  644.                       if (periods[frame][i])
  645.                            indices[frame][i] = (periods[frame][i]
  646.                                             % second) + middle;
  647.                     }
  648.                   }
  649.                 }
  650.             }
  651.           }
  652.           redraw(indices[frame], perind[frame], 1);
  653.           ishow=0; break;
  654.     case 'f': find = (!find);
  655.           break;
  656.     case 'F': save_to_file(pixmap, width, height); ishow=0; break;
  657.     case 'g': if (critical) Remap_arcs(crijec); ishow=0; break;
  658.     case 'G': if (portrait) Remap_arcs(trajec); ishow=0; break;
  659.     case 'H': histogram = (!histogram); 
  660.             if (histogram)
  661.                 HistoMem();
  662.             else
  663.                 FreeHist();
  664.           Clear(trajec);
  665.           if (lyap)
  666.             XStoreName(dpy, trajec, BIF_NAME);
  667.           else if (histogram)
  668.             XStoreName(dpy, trajec, HIST_NAME);
  669.           else
  670.             XStoreName(dpy, trajec, TRAJ_NAME);
  671.           break;
  672.     case '?':
  673.     case 'h': XGetWindowAttributes(dpy, help, &attr);
  674.           if (attr.map_state != IsUnmapped)
  675.             XUnmapWindow(dpy, help);
  676.           else {
  677.             XMapRaised(dpy, help);
  678.               print_help();
  679.           }
  680.           ishow=0; break;
  681.     case 'i': randinit = (!randinit);
  682.           ishow=0; break;
  683.     case 'I': if (idown) {
  684.             XMapRaised(dpy, info);
  685.             stacktop = info;
  686.               init_color(dpy,info,cmap,Colors,STARTCOLOR,MINCOLINDEX,
  687.                             numcolors,numwheels,"endo","Endo", numattrs);
  688.             idown = 0;
  689.           }
  690.           else {
  691.             XUnmapWindow(dpy, info);
  692.             idown = 1;
  693.           }
  694.           break;
  695.     case 'j': clearflag = (!clearflag);
  696.           ishow=0; break;
  697.     case 'J': run = 1; mapindex = -1;
  698.           Save_Parms(1); Change_Parms(0);
  699.           XMapRaised(dpy, lyajec);
  700.           init_color(dpy,lyajec,cmap,Colors,STARTCOLOR,MINCOLINDEX,
  701.                             numcolors,numwheels,"endo","Endo", numattrs);
  702.           ldown=0; Clear(lyajec);
  703.           which = lyajec;
  704.           values.x = 15; values.y = 15;
  705.           values.border_width = 5;
  706.           values.width = XDisplayWidth(dpy, screen);
  707.           values.height = XDisplayHeight(dpy, screen);
  708.           XConfigureWindow(dpy,trajec,
  709.             CWBorderWidth|CWX|CWY|CWWidth|CWHeight,&values);
  710.           Title_Page();
  711.           values.x = Max((XDisplayWidth(dpy,screen)/2)-(width/2),0);
  712.           values.y = Max(INFO_HEIGHT,(XDisplayHeight(dpy,screen)/2) -
  713.             (height / 2)) + 30;
  714.           values.width = width;
  715.           values.height = height;
  716.           XConfigureWindow(dpy,trajec,
  717.             CWBorderWidth|CWX|CWY|CWWidth|CWHeight,&values);
  718.           if (lyap)
  719.               XStoreName(dpy, trajec, BIF_NAME);
  720.           else if (histogram)
  721.               XStoreName(dpy, trajec, HIST_NAME);
  722.           else
  723.               XStoreName(dpy, trajec, TRAJ_NAME);
  724.           Raise_Maps();
  725.           break;
  726. #ifdef USE_3D
  727.     case 'k': tvector.x = (window_center.x - view_point.x) / 2.0;
  728.           tvector.y = (window_center.y - view_point.y) / 2.0;
  729.           tvector.z = (window_center.z - view_point.z) / 2.0;
  730.           TranslateView(tvector);
  731.           Clear(trajec);
  732.           break;
  733.     case 'K': tvector.x = (view_point.x - window_center.x) * 2.0;
  734.           tvector.y = (view_point.y - window_center.y) * 2.0;
  735.           tvector.z = (view_point.z - window_center.z) * 2.0;
  736.           TranslateView(tvector);
  737.           Clear(trajec);
  738.           break;
  739. #endif
  740.     case 'L': /* toggle drawing of bifurcation diagrams */
  741.           /* with and without lyapunov exponents */
  742.           if (olyap == -1)
  743.             olyap = lyap;    /* save original setting */
  744.           lyap = (!lyap);
  745.           if (lyap && olyap)    /* restore positive setting to */
  746.             lyap = olyap;    /* original if it was positive */
  747.           if (lyap >= 2) {
  748.             if (ldown) {
  749.                 XMapRaised(dpy, lyajec);
  750.                 stacktop = lyajec;
  751.                 which = lyajec;
  752.                 Clear(lyajec);
  753.                 ldown=0;
  754.             }
  755.             init_color(dpy,lyajec,cmap,Colors,STARTCOLOR,MINCOLINDEX,
  756.                             numcolors,numwheels,"endo","Endo", numattrs);
  757.             which = lyajec;
  758.           }
  759.           if (lyap == 1) {
  760.             XUnmapWindow(dpy,lyajec);
  761.             ldown = 1;
  762.           }
  763.           break;
  764.     case 'l': if (olyap == -1)
  765.             olyap = lyap;    /* save original setting */
  766.           lyap = (!lyap);
  767.           if (lyap && olyap)    /* restore positive setting to */
  768.             lyap = olyap;    /* original if it was positive */
  769.           if (lyap) {
  770.             if (ldown) {
  771.                 XMapRaised(dpy, lyajec);
  772.                 stacktop = lyajec;
  773.                 which = lyajec;
  774.                 Clear(lyajec);
  775.                 ldown=0;
  776.             }
  777.             init_color(dpy,lyajec,cmap,Colors,STARTCOLOR,MINCOLINDEX,
  778.                             numcolors,numwheels,"endo","Endo", numattrs);
  779.             which = lyajec;
  780.             reset_params();
  781.             XStoreName(dpy, trajec, BIF_NAME);
  782.           }
  783.           else {
  784.             if (adown) {
  785.                 XMapRaised(dpy, canvas);
  786.                 stacktop = canvas;
  787.                 which = canvas;
  788.                 init_color(dpy,canvas,cmap,Colors,STARTCOLOR,MINCOLINDEX,
  789.                             numcolors,numwheels,"endo","Endo", numattrs);
  790.                 Clear(canvas);
  791.                 adown=0;
  792.             }
  793.             which = canvas;
  794.             tx = x; ty = y;
  795.             reset_params();
  796.             params[p1] = tx; params[p2] = ty;
  797.             if (histogram)
  798.                 XStoreName(dpy, trajec, HIST_NAME);
  799.             else
  800.                 XStoreName(dpy, trajec, TRAJ_NAME);
  801.             if (thermometer)
  802.                 Draw_Therm(canvas, pixmap, width, height);
  803.           }
  804.           if (portrait)
  805.             Clear(trajec);
  806.           break;
  807.     case 'M': mandel++;
  808.           if (mandel > 4) mandel = 0; break;
  809.     case 'm': mapindex++; 
  810.           if (mapindex >= NUMMAPS) 
  811.             mapindex=0;
  812.           else if (mapindex < 0)
  813.             mapindex = NUMMAPS - 1;
  814.           map = Maps[mapindex];
  815.           if (numeric)
  816.               deriv = dnumeric;
  817.           else
  818.               deriv = Derivs[mapindex];
  819.           reset_params();
  820.           break;
  821.     case 'N': pdown = (!pdown);
  822.           if (pdown) {
  823.             XUnmapWindow(dpy,prejec);
  824.             if (precrit != 3) precrit = 0;
  825.           }
  826.           else {
  827.             XMapRaised(dpy, prejec);
  828.             stacktop = prejec;
  829.             init_color(dpy,prejec,cmap,Colors,STARTCOLOR,MINCOLINDEX,
  830.                             numcolors,numwheels,"endo","Endo", numattrs);
  831.             if (precrit != 3) precrit = 1;
  832.           }
  833.           break;
  834.     case 'n': negative = (!negative);
  835.           AllFlushBuffer();
  836.           ishow=0; break;
  837. #ifdef USE_3D
  838.     case 'o': tvector.x = avg(0);
  839.           tvector.y = avg(1);
  840.           tvector.z = ((params[p1]-min_x)/x_range) * window_distance;
  841.           TranslateWindow(tvector);
  842.           ScaleWindow(0.5, 0.5);
  843.           Clear(trajec);
  844.           break;
  845.     case 'O': ScaleWindow(2.0, 2.0);
  846.           tvector.x = -avg(0);
  847.           tvector.y = -avg(1);
  848.           tvector.z = -((params[p1]-min_x)/x_range) * window_distance;
  849.           TranslateWindow(tvector);
  850.           Clear(trajec);
  851.           break;
  852. #endif
  853.     case 'P':
  854.     case 'p':     /* toggle trajectory display */
  855.           tdown = (!tdown);
  856.           if (tdown) {
  857.             portrait = 0;
  858.             XUnmapWindow(dpy, trajec);
  859.           }
  860.           else {
  861.             XMapRaised(dpy, trajec);
  862.             stacktop = trajec;
  863.             init_color(dpy,trajec,cmap,Colors,STARTCOLOR,MINCOLINDEX,
  864.                             numcolors,numwheels,"endo","Endo", numattrs);
  865.             Clear(trajec);
  866.             portrait = 1;
  867.             if (thermometer)
  868.                 Draw_Therm(trajec, pixtra, trawidth, traheight);
  869.           }
  870.           break;
  871.     case 'q':
  872.     case 'Q': Clear(trajec); Clear(which); 
  873.           Clear(crijec);
  874.           Cleanup();
  875.           exit(0); break;
  876.     case 'r': AllFlushBuffer(); redraw(indices[frame], perind[frame], 1); 
  877.           ishow=0; break;
  878.     case 'R': AllFlushBuffer(); Redraw(); break;
  879.     case 's': spinning=(!spinning); 
  880.             if (spinning) {
  881.                 spindir=(!spindir);
  882.                 Spin(dpy, cmap, Colors, STARTCOLOR, numcolors, delay, spindir); 
  883.             }
  884.             ishow=0; break;
  885.     case 'S': run=0;
  886.           XSelectInput(dpy,trajec,KeyPressMask|ButtonPressMask|
  887.                 ButtonMotionMask|ButtonReleaseMask|
  888.                 StructureNotifyMask|FocusChangeMask);
  889.           values.x = 15;
  890.           values.y = 15;
  891.           values.border_width = 5;
  892.           values.width = XDisplayWidth(dpy, screen);
  893.           values.height = XDisplayHeight(dpy, screen);
  894.           XConfigureWindow(dpy,trajec,
  895.             CWBorderWidth|CWX|CWY|CWWidth|CWHeight,&values);
  896.           XStoreName(dpy, trajec, SELECT_NAME);
  897.           XMapRaised(dpy, trajec);
  898.           init_color(dpy,trajec,cmap,Colors,STARTCOLOR,MINCOLINDEX,
  899.                             numcolors,numwheels,"endo","Endo", numattrs);
  900.           Show_Maps(mapindex);
  901.           for(;;)
  902.             if (MapSelect())
  903.                 break;
  904.           values.x = Max((XDisplayWidth(dpy,screen)/2)-(width/2),0);
  905.           values.y = Max(INFO_HEIGHT,(XDisplayHeight(dpy,screen)/2) -
  906.             (height / 2)) + 30;
  907.           values.width = width;
  908.           values.height = height;
  909.           XConfigureWindow(dpy,trajec,
  910.             CWBorderWidth|CWX|CWY|CWWidth|CWHeight,&values);
  911.           if (lyap)
  912.               XStoreName(dpy, trajec, BIF_NAME);
  913.           else if (histogram)
  914.               XStoreName(dpy, trajec, HIST_NAME);
  915.           else
  916.               XStoreName(dpy, trajec, TRAJ_NAME);
  917.           XSelectInput(dpy,trajec,KeyPressMask|ButtonPressMask|
  918.             ButtonMotionMask| ButtonReleaseMask|ExposureMask|
  919.             StructureNotifyMask|FocusChangeMask);
  920.           if (portrait) {
  921.               XMapRaised(dpy, trajec);
  922.             tdown = 0;
  923.               stacktop = trajec;
  924.             init_color(dpy,trajec,cmap,Colors,STARTCOLOR,MINCOLINDEX,
  925.                             numcolors,numwheels,"endo","Endo", numattrs);
  926.               Clear(trajec);
  927.             if (thermometer)
  928.                 Draw_Therm(trajec, pixtra, trawidth, traheight);
  929.           }
  930.           break;
  931.     case 't': 
  932.             if (found_arc >= 2) {
  933.                 find_arcs(B0, B1); 
  934.                 t0 = B0; B0 = A0; A0 = t0;
  935.                 t0 = B1; B1 = A1; A1 = t0;
  936.               }
  937.             else if (found_arc == 1) {
  938.                 fprintf(stderr,"Only one intersection found\n");
  939.                 find_arcs(A0, A1); 
  940.             }
  941.             else
  942.                 fprintf(stderr,"%d intersections detected\n",found_arc);
  943.             ishow=0; break;
  944.     case 'T': save_to_file(pixtra, trawidth, traheight); ishow=0; break;
  945.     case 'u': go_back(); break;
  946.     case 'U': go_init(); break;
  947.     case 'v': save_to_file(pixpre, width, height); ishow=0; break;
  948.     case 'V': save_to_file(pixcri, criwidth, criheight); ishow=0; break;
  949.     case 'W': if (numwheels < MAXWHEELS)
  950.                 numwheels++;
  951.                  else
  952.                 numwheels = 0;
  953.                  init_color(dpy,stacktop,cmap,Colors,STARTCOLOR,MINCOLINDEX,
  954.                         numcolors,numwheels,"endo","Endo", numattrs);
  955.               ishow=0; break;
  956.     case 'w': if (numwheels > 0)
  957.                 numwheels--;
  958.               else
  959.                 numwheels = MAXWHEELS;
  960.               init_color(dpy,stacktop,cmap,Colors,STARTCOLOR,MINCOLINDEX,
  961.                         numcolors,numwheels,"endo","Endo", numattrs);
  962.               ishow=0; break;
  963.     case 'x': Clear(which); ishow=0; break;
  964.     case 'X': Destroy_frame(); break;
  965.     case 'y': if (critical) Remap_crit(crijec); ishow=0; break;
  966.     case 'Y': if (portrait) Remap_crit(trajec); ishow=0; break;
  967.     case 'z': Clear(crijec); Clear(prejec); ishow=0; break;
  968.     case 'Z': if (critical) remap_crit(); ishow=0; break;
  969.     default:  GetSpecial(event, key);
  970.               break;
  971.     }
  972.     if ((!idown) && (ishow))
  973.         Show_Info();
  974.     if (spinning)
  975.         Spin(dpy, cmap, Colors, STARTCOLOR, numcolors, delay, spindir); 
  976. }
  977.  
  978. newframe()
  979. {
  980.     extern int Qflag, p_inc, q_inc;
  981.  
  982.     frame = (maxframe + 1) % MAXFRAMES;
  983.     if (frame > maxframe)
  984.         maxframe = frame;
  985.     a_minimums[frame] = min_x;
  986.     b_minimums[frame] = min_y;
  987.     x_inc = x_range / (double)width;
  988.     y_inc = y_range / (double)height;
  989.     a_maximums[frame] = max_x = min_x + x_range;
  990.     b_maximums[frame] = max_y = min_y + y_range;
  991.     point.x = 0;
  992.     point.y = 0;
  993.     maxexp = minexp = 0;
  994.     run = 1;
  995.     x = min_x;
  996.     y = min_y;
  997.     row = 1; numrows = 1;
  998.     if (Qflag == 4) {
  999.         x_inc = x_range / 4.0;
  1000.         y_inc = y_range / 4.0;
  1001.         p_inc = width / 4;
  1002.         q_inc = height / 4;
  1003.         numrows = row = 4;
  1004.     }
  1005.     if (Qflag == 1) {
  1006.         if (x < y) {
  1007.             if (y < max_x)
  1008.             x = y;
  1009.             else
  1010.             run = 0;
  1011.         }
  1012.         else {
  1013.             if (x < max_y)
  1014.             y = x;
  1015.             else
  1016.             run = 0;
  1017.         }
  1018.     }
  1019.     perind[frame] = 0;;
  1020.     Clear(which); Clear(prejec);
  1021. }
  1022.  
  1023. double
  1024. avg(index)
  1025. int index;
  1026. {
  1027.     static int i;
  1028.     static double a;
  1029.  
  1030.     a = 0.0;
  1031.     for (i=0; i<dwell; i++)
  1032.         a += coords[frame][index][i];
  1033.     if (dwell)
  1034.         a /= dwell;
  1035.     return(a);
  1036. }
  1037.